package com.kinghood.productcenter.service.base.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kinghood.infrastructure.api.authority.SysLogModuleEnum;
import com.kinghood.infrastructure.api.authority.UserRemoteVo;
import com.kinghood.infrastructure.model.KingHoodException;
import com.kinghood.infrastructure.model.constant.CommonConstants;
import com.kinghood.infrastructure.model.dto.StatusReqDTO;
import com.kinghood.infrastructure.model.enums.StatusEnum;
import com.kinghood.infrastructure.util.UserUtil;
import com.kinghood.infrastructure.util.base.IdGenUtil;
import com.kinghood.infrastructure.util.excel.EasyExcelUtil;
import com.kinghood.productcenter.common.api.authority.UserRemote;
import com.kinghood.productcenter.common.model.dao.base.BaseAttributeDO;
import com.kinghood.productcenter.common.model.dao.base.BaseAttributeLimitDO;
import com.kinghood.productcenter.common.model.dao.base.BaseAttributeValueDO;
import com.kinghood.productcenter.common.model.dao.product.DownloadCenterDO;
import com.kinghood.productcenter.common.model.dto.base.*;
import com.kinghood.productcenter.common.model.enums.base.AttributeTypeEnum;
import com.kinghood.productcenter.common.model.enums.base.AttributeValueCodeEnum;
import com.kinghood.productcenter.common.model.excel.AttributeExcel;
import com.kinghood.productcenter.common.model.vo.base.AttributeListVO;
import com.kinghood.productcenter.common.model.vo.base.BaseAttributeVO;
import com.kinghood.productcenter.common.model.vo.base.GetAttributePageListVO;
import com.kinghood.productcenter.common.utils.UserNameUtil;
import com.kinghood.productcenter.dao.base.BaseAttributeMapper;
import com.kinghood.productcenter.service.async.IAsyncHuaWeiYunService;
import com.kinghood.productcenter.service.base.IBaseAttributeLimitService;
import com.kinghood.productcenter.service.base.IBaseAttributeService;
import com.kinghood.productcenter.service.base.IBaseAttributeValueService;
import com.kinghood.productcenter.service.product.IDownloadCenterService;
import com.kinghood.productcenter.service.product.handler.ProductBaseHandler;
import com.kinghood.sharding.model.BasePage;
import com.kinghood.sharding.model.KingHoodPageUtil;
import com.kinghood.sharding.model.KingPageResult;
import com.kinghood.sharding.model.PageResponseVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 可选项属性 服务实现类
 * </p>
 *
 * @author KingHood
 * @since 2023-12-20
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class BaseAttributeServiceImpl extends ServiceImpl<BaseAttributeMapper, BaseAttributeDO> implements IBaseAttributeService {
    @Resource
    private IBaseAttributeLimitService limitService;
    @Resource
    private IBaseAttributeValueService valueService;
    @Resource
    private UserRemote userRemote;
    @Value("${base.uploadPath}")
    private String uploadPath;
    @Resource
    private IDownloadCenterService downloadCenterService;
    private final IBaseAttributeValueService attributeValueService;
    private final IAsyncHuaWeiYunService asyncUploadHuaWeiYun;

    /**
     * 属性下拉
     *
     * @return @return {@link List }<{@link BaseAttributeVO }>
     * @author jp
     * @date 2024/01/11 14:02
     */
    @Override
    public List<BaseAttributeVO> getAllAttribute() {
        return this.getBaseMapper().getAllAttribute();
    }

    /**
     * 列表
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/27
     */
    @Override
    public PageResponseVO listAttribute(ListAttributeQueryDTO param) {

        Page<AttributeListVO> result = this.baseMapper.listAttribute(KingHoodPageUtil.getPage(param, param), param);

        Set<Long> userIdList = new HashSet<>();
        for (AttributeListVO record : result.getRecords()) {
            userIdList.add(record.getCreateUserId());
            userIdList.add(record.getUpdateUserId());
            record.setStatusTxt(StatusEnum.getNameByStatus(record.getStatus()));
            record.setValueCodeTxt(AttributeValueCodeEnum.getNameByCode(record.getValueCode()));
            record.setAttributeTypeTxt(AttributeTypeEnum.getNameByCode(record.getAttributeType()));
        }
        userIdList.remove(null);
        if (!CollectionUtils.isEmpty(userIdList)) {
            Map<Long, UserRemoteVo> userMap = userRemote.getUserByIds(new ArrayList<Long>(userIdList));
            for (AttributeListVO record : result.getRecords()) {
                record.setCreateUserName(UserNameUtil.getName(record.getCreateUserId(), userMap));
                record.setUpdateUserName(UserNameUtil.getName(record.getUpdateUserId(), userMap));
            }
        }
        return KingPageResult.getResult(result);
    }

    @Override
    public PageResponseVO<GetAttributePageListVO> getAttributePageList(GetAttributePageListReqDTO param) {

        Page<GetAttributePageListVO> result = this.baseMapper.getAttributePageList(KingHoodPageUtil.getPage(param, param), param);

        Set<Long> userIdList = new HashSet<>();
        for (GetAttributePageListVO record : result.getRecords()) {
            userIdList.add(record.getCreateUserId());
            userIdList.add(record.getUpdateUserId());
            record.setStatusTxt(StatusEnum.getNameByStatus(record.getStatus()));
            record.setValueCodeTxt(AttributeValueCodeEnum.getNameByCode(record.getValueCode()));
            record.setAttributeTypeTxt(AttributeTypeEnum.getNameByCode(record.getAttributeType()));
        }
        userIdList.remove(null);
        if (!CollectionUtils.isEmpty(userIdList)) {
            Map<Long, UserRemoteVo> userMap = userRemote.getUserByIds(new ArrayList<Long>(userIdList));
            for (GetAttributePageListVO record : result.getRecords()) {
                record.setCreateUserName(UserNameUtil.getName(record.getCreateUserId(), userMap));
                record.setUpdateUserName(UserNameUtil.getName(record.getUpdateUserId(), userMap));
            }
        }
        if(!CollectionUtils.isEmpty(result.getRecords())){
            List<Long> attributeIdList = result.getRecords().stream()
                    .map(GetAttributePageListVO::getId).filter(Objects::nonNull)
                    .collect(Collectors.toList());
            List<ValueListByAttributeIdDTO> valueList = attributeValueService.getValueListByAttributeId(attributeIdList,true);
            if(!CollectionUtils.isEmpty(valueList)){
                Map<Long, List<BaseAttributeValueDO>> valueMap = valueList.stream()
                        .collect(Collectors.groupingBy(BaseAttributeValueDO::getAttributeId));
                result.getRecords().forEach(r->r.setValueList(valueMap.get(r.getId())));
            }
        }
        return KingPageResult.getResult(result);
    }

    /**
     * 详情
     *
     * @param id id
     * @author jp
     * @date 2023/12/27
     */
    @Override
    public AttributeReqDTO detailAttribute(Long id) {
        AttributeReqDTO result=new AttributeReqDTO();
        BaseAttributeDO attribute = this.lambdaQuery().eq(BaseAttributeDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .eq(BaseAttributeDO::getId, id)
                .one();
        if (Objects.nonNull(attribute)) {
            BeanUtils.copyProperties(attribute, result);
            if (AttributeValueCodeEnum.isMulti(attribute.getValueCode())) {
                List<AttributeValueReqDTO> values = valueService.lambdaQuery()
                        .eq(BaseAttributeValueDO::getIsDelete, CommonConstants.IS_DELETE_N)
                        .eq(BaseAttributeValueDO::getAttributeId, id)
                        .orderByDesc(BaseAttributeValueDO::getSort, BaseAttributeValueDO::getCreateTime)
                        .list()
                        .stream().map(i -> {
                            AttributeValueReqDTO valueReqDTO = new AttributeValueReqDTO();
                            BeanUtils.copyProperties(i, valueReqDTO);
                            if (AttributeValueCodeEnum.LEVEL_SELECT.getCode().equals(attribute.getValueCode())) {
                                if (!StringUtils.isEmpty(i.getIdPath())) {
                                    valueReqDTO.setLevel(i.getIdPath().split("/").length);
                                } else {
                                    valueReqDTO.setLevel(1);
                                }
                            }
                            return valueReqDTO;
                        }).collect(Collectors.toList());
                // 级联处理
                if (AttributeValueCodeEnum.LEVEL_SELECT.getCode().equals(attribute.getValueCode())) {
                    result.setAttributeValueList(
                            values.stream().filter(tree -> Objects.isNull(tree.getParentId()))
                                    .peek((dept) -> dept.setChildren(getChildrenNode(dept, values))).collect(Collectors.toList())
                    );
                } else {
                    result.setAttributeValueList(values);

                }
            }
            BaseAttributeLimitDO limit = limitService.lambdaQuery().eq(BaseAttributeLimitDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .eq(BaseAttributeLimitDO::getAttributeId, id)
                    .one();
            if (Objects.nonNull(limit)) {
                BaseAttributeLimitReqDTO limitReqDTO = new BaseAttributeLimitReqDTO();
                BeanUtils.copyProperties(limit, limitReqDTO);
                result.setAttributeLimit(limitReqDTO);
            }
            return result;
        }
        return null;
    }

    /**
     * 获取子节点
     *
     * @param parent  parent
     * @param dtoList dto列表
     * @author jp
     * @date 2023/12/26
     */
    private List<AttributeValueReqDTO> getChildrenNode(AttributeValueReqDTO parent, List<AttributeValueReqDTO> dtoList) {
        return dtoList.stream().filter((tree) -> Objects.nonNull(tree.getParentId()) && tree.getParentId().equals(parent.getId()))
                .peek((tree) -> tree.setChildren(getChildrenNode(tree, dtoList))).collect(Collectors.toList());
    }

    /**
     * 新增修改属性
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/27
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addorUpdateAttribute(AttributeReqDTO param) {
        checkAttributeOnly(param);
        checkValueOnly(param);
        if (Objects.isNull(param.getId())) {
            addAttribute(param);
        } else {
            updateAttribute(param);
        }
    }


    /**
     * 添加属性
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/27
     */
    private void addAttribute(AttributeReqDTO param) {
        LocalDateTime now = LocalDateTime.now();
        BaseAttributeDO attribute = new BaseAttributeDO();
        BeanUtils.copyProperties(param, attribute);
        attribute.setId(IdGenUtil.getId());
        attribute.setCreateTime(now);
        attribute.setAttributeType(2);
        attribute.setCreateUserId(UserUtil.getUserId());
        attribute.setUpdateUserId(attribute.getCreateUserId());
        attribute.setUpdateTime(now);
        if (AttributeValueCodeEnum.isMulti(param.getValueCode())) {
            attribute.setValueType(1);
        }
        this.save(attribute);
        // 属性下拉内容
        if (AttributeValueCodeEnum.isMulti(param.getValueCode())) {
            // 保存属性值
            List<BaseAttributeValueDO> attributeValueList = new ArrayList<>();
            // 级联
            if (AttributeValueCodeEnum.LEVEL_SELECT.getCode().equals(param.getValueCode())) {
                setTreeAttribute(param.getAttributeValueList(), attributeValueList, attribute, now, null, null);
            } else {
            // 非级联时
                for (AttributeValueReqDTO valueReqDTO : param.getAttributeValueList()) {
                    BaseAttributeValueDO value = new BaseAttributeValueDO();
                    BeanUtils.copyProperties(valueReqDTO, value);
                    value.setId(IdGenUtil.getId());
                    value.setAttributeId(attribute.getId());
                    value.setCreateTime(now);
                    value.setCreateUserId(UserUtil.getUserId());
                    value.setUpdateUserId(UserUtil.getUserId());
                    value.setUpdateTime(now);
                    attributeValueList.add(value);
                }
            }
            valueService.saveBatch(attributeValueList);
        }
        // 属性限制
        if (Objects.nonNull(param.getAttributeLimit())) {
            BaseAttributeLimitDO limit = new BaseAttributeLimitDO();
            BeanUtils.copyProperties(param.getAttributeLimit(), limit);
            limit.setId(IdGenUtil.getId());
            limit.setAttributeId(attribute.getId());
            limit.setCreateTime(now);
            limit.setCreateUserId(UserUtil.getUserId());
            limit.setUpdateUserId(UserUtil.getUserId());
            limit.setUpdateTime(now);
            limitService.save(limit);
        }
    }

    /**
     * 设置树属性
     *
     * @param attributeList 属性列表
     * @param result        结果
     * @param attribute     属性
     * @param now           当前时间
     * @param parentId      父id
     * @author jp
     * @date 2023/12/27
     */
    private void setTreeAttribute(List<AttributeValueReqDTO> attributeList, List<BaseAttributeValueDO> result, BaseAttributeDO attribute, LocalDateTime now,
                                  Long parentId, String idPath) {
        for (AttributeValueReqDTO valueReqDTO : attributeList) {
            BaseAttributeValueDO value = new BaseAttributeValueDO();
            BeanUtils.copyProperties(valueReqDTO, value);
            if (Objects.isNull(value.getId())) {
                value.setId(IdGenUtil.getId());
                value.setCreateTime(now);
                value.setCreateUserId(UserUtil.getUserId());
            }
            value.setAttributeId(attribute.getId());
            value.setUpdateUserId(UserUtil.getUserId());
            value.setUpdateTime(now);
            value.setParentId(parentId);
            if (StringUtils.isEmpty(idPath)) {
                value.setIdPath(value.getId()+"");
            } else {
                value.setIdPath(idPath+"/"+value.getId());
            }
            if (!CollectionUtils.isEmpty(valueReqDTO.getChildren())) {
                setTreeAttribute(valueReqDTO.getChildren(), result, attribute, now, value.getId(), value.getIdPath());
            }
            result.add(value);
        }
    }

    /**
     * 修改属性
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/27
     */
    private void updateAttribute(AttributeReqDTO param) {
        BaseAttributeDO updateAttribute  = new BaseAttributeDO();
        if (AttributeValueCodeEnum.isMulti(param.getValueCode())) {
            List<BaseAttributeValueDO> oldValues = valueService.lambdaQuery()
                    .eq(BaseAttributeValueDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .eq(BaseAttributeValueDO::getAttributeId, param.getId())
                    .list();
            List<Long> removeValueIds = oldValues.stream().map(i -> i.getId()).collect(Collectors.toList());
            removeValueIds.removeAll(getLevelAllidList(param.getAttributeValueList()));
            if (!CollectionUtils.isEmpty(removeValueIds)) {
                for (Long removeValueId : removeValueIds) {
                    int productUsedNum = this.baseMapper.countUsedByValueId(removeValueId);
                    if (productUsedNum > 0) {
                        throw new KingHoodException(-1 , "属性值存在关联商品，无法删除");
                    }
                }
            }
            updateAttribute.setValueType(1);
        }
        LocalDateTime now = LocalDateTime.now();
        BaseAttributeDO oldAttribute = this.getById(param.getId());
        BeanUtils.copyProperties(param, updateAttribute);
        updateAttribute.setCreateTime(oldAttribute.getCreateTime());
        updateAttribute.setCreateUserId(oldAttribute.getCreateUserId());
        updateAttribute.setAttributeName(oldAttribute.getAttributeName());
        updateAttribute.setUpdateTime(now);
        updateAttribute.setUpdateUserId(UserUtil.getUserId());
        this.updateById(updateAttribute);
        // 属性下拉内容
        if (AttributeValueCodeEnum.isMulti(param.getValueCode())) {
            // 保存属性值
            List<BaseAttributeValueDO> attributeValueList = new ArrayList<>();
            // 级联数据处理
            if (AttributeValueCodeEnum.LEVEL_SELECT.getCode().equals(param.getValueCode())) {
                setTreeAttribute(param.getAttributeValueList(), attributeValueList, updateAttribute, now, null, null);
            } else {
                // 非级联时
                for (AttributeValueReqDTO valueReqDTO : param.getAttributeValueList()) {
                    BaseAttributeValueDO value = new BaseAttributeValueDO();
                    BeanUtils.copyProperties(valueReqDTO, value);
                    if (Objects.isNull(value.getId())) {
                        value.setId(IdGenUtil.getId());
                        value.setCreateTime(now);
                        value.setCreateUserId(UserUtil.getUserId());
                    }
                    value.setAttributeId(oldAttribute.getId());
                    value.setUpdateUserId(value.getCreateUserId());
                    value.setUpdateTime(now);
                    attributeValueList.add(value);
                }
            }
            // 删除不在当前集合中的标签值
            List<Long> updateIds = attributeValueList.stream().map(BaseAttributeValueDO::getId)
                    .collect(Collectors.toList());
            valueService.lambdaUpdate().set(BaseAttributeValueDO::getIsDelete, CommonConstants.IS_DELETE_Y)
                    .set(BaseAttributeValueDO::getUpdateTime, now)
                    .set(BaseAttributeValueDO::getUpdateUserId, UserUtil.getUserId())
                    .eq(BaseAttributeValueDO::getAttributeId, param.getId())
                    .notIn(!CollectionUtils.isEmpty(updateIds), BaseAttributeValueDO::getId, updateIds)
                    .update();
            valueService.saveOrUpdateBatch(attributeValueList);
        }
        // 属性限制
        if (Objects.nonNull(param.getAttributeLimit())) {
            BaseAttributeLimitDO limit = new BaseAttributeLimitDO();
            BeanUtils.copyProperties(param.getAttributeLimit(), limit);
            if (Objects.isNull(limit.getId())) {
                limit.setId(IdGenUtil.getId());
                limit.setCreateTime(now);
                limit.setCreateUserId(UserUtil.getUserId());
                limitService.lambdaUpdate().eq(BaseAttributeLimitDO::getAttributeId, param.getId())
                        .eq(BaseAttributeLimitDO::getIsDelete, CommonConstants.IS_DELETE_N)
                        .set(BaseAttributeLimitDO::getIsDelete, CommonConstants.IS_DELETE_Y)
                        .set(BaseAttributeLimitDO::getUpdateTime, now)
                        .set(BaseAttributeLimitDO::getUpdateUserId, UserUtil.getUserId())
                        .update();
            }
            limit.setAttributeId(oldAttribute.getId());
            limit.setUpdateUserId(limit.getCreateUserId());
            limit.setUpdateTime(limit.getCreateTime());
            limitService.saveOrUpdate(limit);
        }
    }

    /**
     * 获取级联的所有id
     *
     * @param param 参数
     * @return @return {@link List }<{@link Long }>
     * @author jp
     * @date 2024/01/24 09:30
     */
    private List<Long> getLevelAllidList(List<AttributeValueReqDTO> param) {
        List<Long> result = new ArrayList<>();
        List<AttributeValueReqDTO> levelData = new ArrayList<>(param);
        List<AttributeValueReqDTO> temp = new ArrayList<>();
        while (!CollectionUtils.isEmpty(levelData)) {
            for (AttributeValueReqDTO levelDatum : levelData) {
                if (Objects.nonNull(levelDatum.getId())) {
                    result.add(levelDatum.getId());
                }
                if (!CollectionUtils.isEmpty(levelDatum.getChildren())) {
                    temp.addAll(levelDatum.getChildren());
                }
            }
            levelData.clear();
            levelData.addAll(temp);
            temp.clear();
        }
        return result;
    }

    /**
     * 删除
     *
     * @param id id
     * @author jp
     * @date 2023/12/27
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delAttributeById(Long id) {
        BaseAttributeDO brand = this.getById(id);
        if (Objects.nonNull(brand) && !brand.getStatus().equals(CommonConstants.DISABLE)) {
            throw new KingHoodException(-1 , "只有停用状态的才可操作删除");
        }
        int productUsedNum = this.baseMapper.countProductUsed(id);
        if (productUsedNum > 0) {
            throw new KingHoodException(-1 , "当前属性存在关联商品，无法删除");
        }
        valueService.lambdaUpdate().set(BaseAttributeValueDO::getIsDelete, CommonConstants.IS_DELETE_Y)
                .set(BaseAttributeValueDO::getUpdateTime, LocalDateTime.now())
                .set(BaseAttributeValueDO::getUpdateUserId, UserUtil.getUserId())
                .eq(BaseAttributeValueDO::getAttributeId, id)
                .eq(BaseAttributeValueDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .update();
        this.lambdaUpdate().set(BaseAttributeDO::getIsDelete, CommonConstants.IS_DELETE_Y)
                .set(BaseAttributeDO::getUpdateTime, LocalDateTime.now())
                .set(BaseAttributeDO::getUpdateUserId, UserUtil.getUserId())
                .eq(BaseAttributeDO::getId, id)
                .eq(BaseAttributeDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .update();
    }


    /**
     * 更新属性状态
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/27
     */
    @Override
    public void updateAttributeStatus(StatusReqDTO param) {
        this.lambdaUpdate().set(BaseAttributeDO::getStatus, param.getStatus())
                .set(BaseAttributeDO::getUpdateTime, LocalDateTime.now())
                .set(BaseAttributeDO::getUpdateUserId, UserUtil.getUserId())
                .eq(BaseAttributeDO::getId, param.getId())
                .eq(BaseAttributeDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .update();

    }

    /**
     * 检查是否唯一
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/21
     */
    private void checkAttributeOnly(AttributeReqDTO param){
        Long count;
        if (Objects.isNull(param.getId())) {
            count = this.lambdaQuery().eq(BaseAttributeDO::getAttributeCode, param.getAttributeCode())
                    .eq(BaseAttributeDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .count();
            if (count > 0) {
                throw new KingHoodException(-1 ,"编码已存在");
            }
            count = this.lambdaQuery().eq(BaseAttributeDO::getAttributeName, param.getAttributeName())
                    .eq(BaseAttributeDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .count();
            if (count > 0) {
                throw new KingHoodException(-1 ,"名称已存在");
            }
        } else {
            count = this.lambdaQuery().eq(BaseAttributeDO::getAttributeCode, param.getAttributeCode())
                    .ne(BaseAttributeDO::getId, param.getId())
                    .eq(BaseAttributeDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .count();
            if (count > 0) {
                throw new KingHoodException(-1 ,"编码已存在");
            }
            count = this.lambdaQuery().eq(BaseAttributeDO::getAttributeName, param.getAttributeName())
                    .ne(BaseAttributeDO::getId, param.getId())
                    .eq(BaseAttributeDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .count();
            if (count > 0) {
                throw new KingHoodException(-1 ,"名称已存在");
            }
        }
    }

    /**
     * 检查数据值唯一
     *
     * @param param 参数
     * @author jp
     * @date 2023/12/27
     */
    private void checkValueOnly(AttributeReqDTO param) {
        if (!CollectionUtils.isEmpty(param.getAttributeValueList())) {
            long size = param.getAttributeValueList().size();
            if (size > 1) {
                long codeSize = param.getAttributeValueList().stream().map(i -> i.getCode()).distinct().count();
                if (codeSize < size) {
                    throw new KingHoodException(-1 ,"存在重复编码");
                }
                long nameSize = param.getAttributeValueList().stream().map(i -> i.getValue()).distinct().count();
                if (nameSize < size) {
                    throw new KingHoodException(-1 ,"存在重复值");
                }
            }
        }
    }

    /**
     * 批量获取属性
     *
     * @param param 参数
     * @author jp
     * @date 2024/01/03
     */
    @Override
    public List<AttributeReqDTO> attributeByCodes(AttributeCodesReqDTO param) {
        List<BaseAttributeDO> attribute = this.lambdaQuery().eq(BaseAttributeDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .in(BaseAttributeDO::getAttributeCode, param.getCodes())
                .list();
        if (!CollectionUtils.isEmpty(attribute)) {
            List<AttributeReqDTO> result = new ArrayList<>();
            for (BaseAttributeDO attributeDO : attribute) {
                AttributeReqDTO attributeReqDTO = new AttributeReqDTO();
                BeanUtils.copyProperties(attributeDO, attributeReqDTO);
                result.add(attributeReqDTO);
            }
            List<Long> attributeIds = result.stream().map(i -> i.getId()).collect(Collectors.toList());
            Map<Long, List<AttributeValueReqDTO>> valueMap = valueService.lambdaQuery()
                    .eq(BaseAttributeValueDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .in(BaseAttributeValueDO::getAttributeId, attributeIds)
                    .orderByDesc(BaseAttributeValueDO::getSort, BaseAttributeValueDO::getCreateTime)
                    .list()
                    .stream().map(i -> {
                        AttributeValueReqDTO valueReqDTO = new AttributeValueReqDTO();
                        BeanUtils.copyProperties(i, valueReqDTO);
                        valueReqDTO.setCodeValue("["+valueReqDTO.getCode()+"]"+valueReqDTO.getValue());
                        return valueReqDTO;
                    }).collect(Collectors.groupingBy(AttributeValueReqDTO::getAttributeId));
            Map<Long, BaseAttributeLimitReqDTO> limitMap = limitService.lambdaQuery()
                    .eq(BaseAttributeLimitDO::getIsDelete, CommonConstants.IS_DELETE_N)
                    .in(BaseAttributeLimitDO::getAttributeId, attributeIds)
                    .list().stream().map(i -> {
                        BaseAttributeLimitReqDTO limitReqDTO = new BaseAttributeLimitReqDTO();
                        BeanUtils.copyProperties(i, limitReqDTO);
                        return limitReqDTO;
                    }).collect(Collectors.toMap(BaseAttributeLimitReqDTO::getAttributeId, i -> i, (k1,k2) -> k1));
            for (AttributeReqDTO item : result) {
                item.setAttributeValueList(valueMap.get(item.getId()));
                item.setAttributeLimit(limitMap.get(item.getId()));
            }
            return result;
        }
        return null;
    }

    /**
     * 下载属性
     *
     * @param param    参数
     * @param response 回答
     * @author jp
     * @date 2024/01/04
     */
    @Override
    public void downloadAttribute(ListAttributeQueryDTO param, HttpServletResponse response) {
        String fileName = StringUtils.isEmpty(param.getFileName()) ? "属性数据" : param.getFileName();
        String sheetName = StringUtils.isEmpty(param.getSheetName()) ? "属性" : param.getSheetName();

        if (Objects.isNull(param.getPage())) {
            param.setPage(new BasePage());
            param.getPage().setPageSize(99999);
        }
        PageResponseVO responseVO = listAttribute(param);
        List<AttributeListVO> dataList = responseVO.getList();
        List<AttributeExcel> result = new ArrayList<>();
        for (AttributeListVO attributeVO : dataList) {
            AttributeExcel excel = new AttributeExcel();
            BeanUtils.copyProperties(attributeVO, excel);
            result.add(excel);
        }
        // 保存到数据库
        LocalDateTime now = LocalDateTime.now();
        DownloadCenterDO downloadCenterDO = new DownloadCenterDO();
        try {
            String showParam = "";
            if (!CollectionUtils.isEmpty(param.getDownloadField())) {
                showParam = String.join(",", param.getDownloadField());
            }
            String path = EasyExcelUtil.export(response, fileName, sheetName, result, AttributeExcel.class,
                    showParam, uploadPath);
            File file = new File(path);
            downloadCenterDO.setId(IdGenUtil.getId())
                    .setFileName(file.getName())
                    .setModule(SysLogModuleEnum.PRODUCT_ATTRIBUTE.getType())
                    .setType(2)
                    .setFileSize(ProductBaseHandler.getSizeName(file.length()))
                    .setUrl(path)
                    .setCreateTime(now)
                    .setUpdateTime(now)
                    .setCreateUserId(UserUtil.getUserId())
                    .setUpdateUserId(UserUtil.getUserId());
            downloadCenterService.save(downloadCenterDO);
            asyncUploadHuaWeiYun.uploadToHuaWeiYun(downloadCenterDO.getId(), file.getAbsolutePath());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 删除属性值检查
     *
     * @param valueId 值id
     * @return @return {@link Object }
     * @author jp
     * @date 2024/01/11 14:18
     */
    @Override
    public void checkAttributeValueUsed(Long valueId) {
        Integer count = this.baseMapper.countUsedByValueId(valueId);
        if (count > 0) {
            throw new KingHoodException(-1, "属性值下有商品无法删除");
        }
    }

    @Override
    public Map<String, String> getCodeNameMap(List<String> realAttribute) {
        Map<String, String> result = this.lambdaQuery()
                .eq(BaseAttributeDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .in(BaseAttributeDO::getAttributeCode, realAttribute)
                .list()
                .stream()
                .collect(Collectors.toMap(BaseAttributeDO::getAttributeCode, BaseAttributeDO::getAttributeName, (x,y) -> x));
        return result;
    }

    @Override
    public List<Long> getAttributeIdList(List<String> attributeCode) {

        // 由于用于编辑，所以不能考虑是否启用的状态，因为停用状态的话，应该提前就提醒了
        List<BaseAttributeDO> attributeList = new LambdaQueryChainWrapper<>(this.getBaseMapper())
                .in(BaseAttributeDO::getAttributeCode, attributeCode)
                .eq(BaseAttributeDO::getIsDelete, CommonConstants.IS_DELETE_N)
                .list();

        List<Long> templateAttributeIdList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(attributeList)){
            templateAttributeIdList = attributeList.stream().map(BaseAttributeDO::getId).collect(Collectors.toList());
        }
        return templateAttributeIdList;
    }
}
